package cn.dduan.fool.design.pattern.great.factory;

/**
 * 抽象工厂模式
 * <p>
 * 优点：
 * 1、主要用于创建相关对象的家族（例如：生成一台汽车，生产过程中需要安装发动机、空调等等。。。）
 * 2、当一个产品族中需要被设计在一起工作时，通过抽象工厂模式，能够保证客户端始终只使用同一个产品族中的对象
 * <p>
 * 缺点：
 * 1、添加新的行为时比较麻烦
 * 2、如果需要添加一个新产品族对象时，需要更改接口及其下所有子类，这必然会带来很大的麻烦
 * <p>
 * 工厂方法模式与抽象工厂模式的区别：
 * 1、工厂方法只有一个抽象产品类和一个抽象工厂类，但可以派生出多个具体产品类和具体工厂类，每个具体工厂类只能创建一个具体产品类的实例
 * 2、抽象工厂模式拥有多个抽象产品类（产品族）和一个抽象工厂类，每个抽象产品类可以派生出多个具体产品类；抽象工厂类也可以派生出多个具体工厂类，同时每个具体工厂类可以创建多个具体产品类的实例
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
public class AbstractFactory {
    public static void main(String[] args) {
        // 生产宝马3系
        System.out.println("生产宝马3系:");
        FactoryBMW330 bmw330 = new FactoryBMW330();
        bmw330.createEngine();
        bmw330.createAircondition();

        // 生产宝马5系
        System.out.println("生产宝马5系:");
        FactoryBMW550 bmw550 = new FactoryBMW550();
        bmw550.createEngine();
        bmw550.createAircondition();
    }
}

/**
 * 抽象工厂-接口
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
interface AbstractFactory1 {
    //制造发动机
    public Engine createEngine();

    //制造空调
    public Aircondition createAircondition();
}

/**
 * 工厂接口实现
 * 生产宝马3系
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
class FactoryBMW330 implements AbstractFactory1 {
    @Override
    public Engine createEngine() {
        return new EngineA();
    }

    @Override
    public Aircondition createAircondition() {
        return new AirconditionA();
    }
}

/**
 * 工厂接口实现
 * 生产宝马5系
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
class FactoryBMW550 implements AbstractFactory1 {
    @Override
    public Engine createEngine() {
        return new EngineB();
    }

    @Override
    public Aircondition createAircondition() {
        return new AirconditionB();
    }
}


/**
 * 抽象产品类-汽车配件-发动机
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
interface Engine {
}

/**
 * 具体产品类-汽车配件-发动机
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
class EngineA implements Engine {
    public EngineA() {
        System.out.println("制造-->" + this.getClass().getSimpleName());
    }
}

/**
 * 具体产品类-汽车配件-发动机
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
class EngineB implements Engine {
    public EngineB() {
        System.out.println("制造-->" + this.getClass().getSimpleName());
    }
}

/**
 * 抽象产品类-汽车配件-空调
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
interface Aircondition {
}

/**
 * 具体产品类-汽车配件-空调
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
class AirconditionA implements Aircondition {
    public AirconditionA() {
        System.out.println("制造-->" + this.getClass().getSimpleName());
    }
}

/**
 * 具体产品类-汽车配件-空调
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
class AirconditionB implements Aircondition {
    public AirconditionB() {
        System.out.println("制造-->" + this.getClass().getSimpleName());
    }
}